<script setup lang="ts">
import { ref, type Ref } from "vue";
import { ElText, ElIcon, ElTooltip } from "element-plus";
import { Delete, SetUp } from "@element-plus/icons-vue";
import textDetection from "./textDetection";
import OCRModel from "../training/OCRModel";

const files: Ref<Array<File>> = ref([]);
const dragging = ref(false);
const input = ref();
const imgBox = ref();
let model;

const initModel = async () => {
  model = new OCRModel();
  await model.load();
};

const inputClick = () => {
  input.value.click();
};

const dropFiles = (event) => {
  dragging.value = false;

  for (const file of event.dataTransfer.files) {
    files.value.push(file);
  }
};

const inputFiles = (event) => {
  for (const file of event.target.files) {
    files.value.push(file);
  }
  input.value.value = "";
};

const deleteFile = (file) => {
  const index = files.value.indexOf(file);
  if (index > -1) {
    files.value.splice(files.value.indexOf(file), 1);
  }
  clearImg();
};

let currentFile = ref();
const img = ref();

const viewImg = (imageFile) => {
  currentFile.value = imageFile;
  img.value.src = URL.createObjectURL(imageFile);
  img.value.onload = () => {
    handleImg();
  };
};

const clearImg = () => {
  URL.revokeObjectURL(img.value.src);
  img.value.src = "";
  currentFile.value = null;
  [...imgBox.value.children].forEach((e) => e.remove());
};

const handleImg = async () => {
  await initModel();

  const result = textDetection(img.value);

  imgBox.value.innerHTML = ''

  for (let i = 0; i < result.length; i++) {
    const canvas = result[i];

    imgBox.value.append(canvas);

    const text = await model.predict(canvas);
    const span = document.createElement("span");
    span.innerText = text;
    imgBox.value.append(span);
  }
};
</script>

<template>
  <div class="container">
    <div class="select-container">
      <div
        class="drag-box"
        :class="{ dragging: dragging }"
        draggable="true"
        @dragover="dragging = true"
        @dragleave="dragging = false"
        @dragover.prevent
        @drop.prevent="dropFiles($event)"
        @click="inputClick"
      >
        <input
          ref="input"
          class="file-input"
          type="file"
          multiple
          @change="inputFiles"
        />
        <div class="offset-point"></div>
        <div class="offset-point point-1"></div>
        <div class="offset-point point-2"></div>
        <span>拖入文件/点击</span>
      </div>
      <div class="file-list" v-show="files.length > 0">
        <div class="file-row" v-for="file of files" :key="file.name">
          <ElText class="file-name" truncated>{{ file.name }}</ElText>
          <ElTooltip content="处理图片">
            <ElIcon :size="20" color="#5af" @click="viewImg(file)">
              <SetUp />
            </ElIcon>
          </ElTooltip>
          <ElTooltip content="删除文件">
            <ElIcon :size="20" color="#a5f" @click="deleteFile(file)">
              <Delete />
            </ElIcon>
          </ElTooltip>
        </div>
      </div>
    </div>
    <div class="view-container" v-show="currentFile">
      <div>
        <img ref="img" />
      </div>
      <div ref="imgBox" class="img-box"></div>
    </div>
  </div>
</template>

<style scoped>
.container {
  width: 100%;
}

.select-container {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}

.drag-box {
  position: relative;
  cursor: pointer;
  color: #fff;
  font-size: 12px;
  width: 200px;
  height: 200px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px dashed rgba(255, 255, 255, 0.5);
  border-radius: 5px;
  box-shadow: 1px 1px 10px rgba(255, 255, 255, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}

.offset-point {
  display: none;
  width: 0px;
  height: 0px;
  border: 3px solid transparent;
  border-bottom-color: #fff;
  position: absolute;
  left: 0;
  top: 0;
  offset: path("M 0 0 L 200 0 L 200 200 L 0 200 z") 0% auto 90deg;
}

.dragging .offset-point {
  display: block;
  animation: 3s offset-point-move linear infinite;
}

.dragging .point-1 {
  display: block;
  border-width: 2px;
  animation: 3s 20ms offset-point-move linear infinite;
}

.dragging .point-2 {
  display: block;
  border-width: 1px;
  animation: 3s 40ms offset-point-move linear infinite;
}

@keyframes offset-point-move {
  0% {
    offset-distance: 0%;
  }

  100% {
    offset-distance: 100%;
  }
}

.file-input {
  display: none;
  position: relative;
  bottom: -100px;
}

.file-list {
  margin-left: 100px;
  padding: 10px 20px;
  color: #fff;
  border: 1px ridge rgba(255, 255, 255, 0.1);
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.05);
  box-shadow: 1px 1px 10px rgba(255, 255, 255, 0.1);
}

.file-row {
  margin: 10px;
  border-bottom: 5px double rgba(255, 255, 255, 0.2);
}

.file-name {
  width: 200px;
  margin-right: 10px;
  color: #fff;
}

.el-icon {
  cursor: pointer;
  margin-left: 5px;
}

.view-container {
  width: 100%;
  margin-top: 50px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.img-box {
  flex-grow: 0;
  padding: 10px 20px;
  color: #fff;
  border: 2px ridge rgba(255, 255, 255, 0.1);
  box-shadow: 1px 1px 10px rgba(255, 255, 255, 0.1);
  border-radius: 5px;
}
.img-box > * {
  margin-left: 5px;
}
</style>
